/**
 * Created by 杨浩宇 on 2016-01-13.
 */
/**
 * 顶部菜单插件
 * $('div').headMenu({menus : {}});
 * 必须给出div元素
 * 入参menus格式：
 * {
 *   id : '菜单id',
 *   name : '菜单名称',
 *   level : '菜单层级，1-3',
 *   children : [子菜单]
 * }
 * Created by 杨浩宇 on 2016-01-07.
 */
;
(function ($, window, document, undefined) {
    /**
     * 插件对象实例。每个jquery元素对应一个插件实例
     * @type {Array}
     * [{
     *   key : jquery元素的ID
     *   value : 插件对象实例
     * }]
     */
    var pluginArray = [];

    /**
     * 插件对象
     * @param $ele jquery实例
     * @constructor
     */
    function Plugin($ele) {
        this.$element = $ele;
    }

    /**
     * 插件对象初始化方法
     * @param setting
     */
    Plugin.prototype._init = function (setting) {
        this.default = {
            menus: []
        };

        this.options = $.extend({}, this.default, setting);

        this.menuIDArry = this.menuTimeArry = "";

        var self = this;

        this.createDOM();


        //菜单
        this.$element.find(".menu_lv1_Obj .lv1").each(function () {
            //设置一级菜单总宽
            var w = j = 0;
            $(this).children("li").each(function () {
                if ($(this).attr("id") != "" && $(this).attr("id") != null && $(this).attr("id") != "unbefined") {
                    $(this).addClass("jt");
                }
                w += $(this).outerWidth(true);
                j++;
            });
            $(this).css({width: w + "px"});
            self.menuIDArry = new Array(j);
        });
        this.$element.find(".menu_lv1_Obj .lv1 li").hover(
            function (e) {
                self.allTowMenuHide();
                self.showHideMenu($(this), true);
            }, function (e) {
                //设置微秒后执行隐藏
                var n = null, s = $(this).attr("id");
                if (s.indexOf("menu_lv1_") >= 0) {
                    n = s.replace("menu_lv1_", "");
                    self.menuIDArry[parseInt(n)] = $(this);
                    self.menuTimeArry = setTimeout(function () {
                        $("#headMenu").width(43);
                        self.showHideMenu(self.menuIDArry[n], false);
                    }, 1);
                }
            }
        );

        new SellerScroll("#headMenuObj");
    };

    /**
     * 创建菜单元素
     */
    Plugin.prototype.createDOM = function () {
        var tempate =
            '<div class="Menu" id="headMenuObj">' +
            '<div class="list menu_lv1_Obj">' +
            '<ul class="lv1"></ul>' +
            '</div>' +
            '<a href="javascript:;" class="arrowL"></a> <a href="javascript:;" class="arrowR"></a>' +
            '</div>' +
            '<div class="lv1 menu_lv2_Obj"></div>';

        this.$element.append(tempate);

        this.createMenus(null, this.options.menus);
    };

    /**
     * 创建菜单元素
     * @param $ul
     * @param menus
     */
    Plugin.prototype.createMenus = function ($ul, menus) {
        if ($ul === null || $ul === undefined) {
            $ul = this.$element.find('ul.lv1');
        }
        if ($ul.hasClass('lv3') && $ul.find('.up').length === 0) {
            $ul.append('<li class="up"></li>');
        }
        var self = this;
        var rootList = [];
        $.each(menus, function (index, item) {
            var hasChildren = item.children !== null && item.children !== undefined && item.children.length > 0;
            var li = '<li id="menuId" data-menu = "dataMenu"><a href="#">menuName</a></li>';
            if (!hasChildren) {
                li = '<li id="menuId" data-menu = "dataMenu"><div class="mark"></div>' +
                    '<a href="#" data-id="dataMenu" data-authUrl="menuPage" data-name="menuName" data-authPath="menuModule" data-loadtype="menuLoadType"><b><i>menuName</i></b></a></li>';
            }
            if (item.level === 1) {
                rootList.push(item.name);
                if (item.icon) {
                    li = '<li id="menuId" data-menu = "dataMenu" class="' + item.icon + '"></li>';
                } else { //设置一个默认的class
                    li = '<li id="menuId" data-menu = "dataMenu" class="menu-null"></li>';
                }
            }
            var $li = $(li.replace(/menuId/g, 'menu_lv' + item.level + '_' + index).
            replace(/dataMenu/g, item.id).
            replace(/menuName/g, item.name).
            replace(/menuPage/g, item.authUrl).
            replace(/menuModule/g, item.authPath).
            replace(/menuLoadType/g, item.loadType));
            if (item.level > 1) {
                $li.removeAttr('id');
            }
            if (!hasChildren) {
                $li.on('click', {}, function () {
                    self.$element.find('.menu_lv1_Obj .lv1 li').each(function () {
                        self.showHideMenu($(this), false);
                        $("#headMenu").width(43);
                    })

                });
            }
            $ul.append($li);
            if (hasChildren) {
                var menuId = 'menu_lv' + (item.level + 1) + '_' + index;
                var $subUl = $('<ul class="lv' + (item.level + 1) + '" id="' + menuId + '"><div class="outerDiv"></div></ul>');
                if (item.level === 1) {
                    self.$element.find('.menu_lv2_Obj').append($subUl);
                } else {
                    $li.append($subUl);
                }
                self.createMenus($subUl.find(".outerDiv"), item.children);
            } else {
                if (item.level === 1) {
                    var menuId = 'menu_lv' + (item.level + 1) + '_' + index;
                    var $subUl = $('<ul class="lv' + (item.level + 1) + '" id="' + menuId + '"></ul>');
                    self.$element.find('.menu_lv2_Obj').append($subUl);
                }
            }
        });
        if (rootList.length > 0) { //循环给隐藏的二级菜单添加header
            var i = 0;
            $(".lv2").each(function () {
                $(this).prepend('<li class="top">' + rootList[i] + '</li>');
                i++;
            });
        }
        if (!$ul.hasClass('lv1') && $ul.find('.bottom').length === 0) {
            //  $ul.append('<li class="bottom"></li>');
        }

    };

    Plugin.prototype.showHideMenu = function (obj, bool) {
        var n = null, lv2 = null, s = obj.attr("id");
        var self = this;
        clearTimeout(this.menuTimeArry);
        if (s.indexOf("menu_lv1_") >= 0) {
            n = s.replace("menu_lv1_", "");
            lv2 = this.$element.find("#menu_lv2_" + n);
            if (bool && lv2.length > 0) {
                obj.addClass("move");
                if (lv2.children("li").length > 0) {
                    //执行二级菜单显示，提示：可放到另一个函数里执行，但对象要对
                    //lv2.slideDown('fast').show();
                    lv2.show();
                    var mtop = obj.offset().top
                    var mheight = lv2.height(), bodyh = $('body').height();
                    if ((mtop + mheight) > bodyh) { //判断二级菜单的高度加上top的值是否大于body总高度，防止二级菜单展示不全。
                        mtop = bodyh - mheight - 22;
                        mtop -= 3;
                        if (mtop <= 50) {//小于了header的高度则设置滚动方式
                            mtop = 52;
                            lv2.css({
                                "height": (bodyh - 22 - 56) + "px"
                            });
                            lv2.find(".outerDiv").css({
                                "overflow-y": "auto",
                                "overflow-x": "hidden",
                                "height": (bodyh - 22 - 56 - 35) + "px"
                            });
                        }
                    }
                    if ((mheight) > bodyh) {
                        lv2.css({
                            "height": (bodyh - 22 - 56) + "px"
                        });
                        lv2.find(".outerDiv").css({
                            "overflow-y": "auto",
                            "overflow-x": "hidden",
                            "height": (bodyh - 22 - 56 - 35) + "px"
                        });
                        mtop = 52;
                    }
                    lv2.css({left: 41 + obj.offset().left + "px", top: mtop + "px", display: "block"});
                    //if (lv2.width() == 200) {
                    lv2.css({width: "160px"});
                    //设置二级菜单总宽
                    //var w=0;
                    lv2.children("li").each(function () {
                        //w += $(this).outerWidth(true);
                        //有子菜单就加箭头
                        if ($(this).children("ul.lv3").length > 0) {
                            $(this).addClass("jt");
                        }
                    });
                    //lv2.css({width:w+"px"});
                    //设置二级菜单悬浮动作
                    lv2.hover(function (e) {
                        clearTimeout(self.menuTimeArry);
                    }, function (e) {
                        self.allTowMenuHide();
                        $("#headMenu").width(43);
                    });
                    //设置三级菜单滑动
                    lv2.children("li").hover(
                        function (e) {
                            //  $(this).children(".lv3").slideDown('fast').show();
                            $(this).children(".lv3").show();
                        }, function (e) {
                            $(this).children(".lv3").hide();
                            //$(this).children(".lv3").slideUp('fast');
                        }
                    );
                    //   }
                    if (lv2.offset().left + lv2.width() > getBodyVal().width) {
                        var l = lv2.offset().left - (lv2.offset().left + lv2.width() - getBodyVal().width);
                        l = l <= 0 ? 0 : l;
                        lv2.css({left: l + "px"});
                    }
                    //end
                } else {
                    //当没有载入二级菜单时显示loading
                    //lv2.css({width:"100px", left:obj.offset().left+"px", top:obj.offset().top+31+"px", display:"block"});
                    lv2.css({left: obj.offset().left + "px", top: obj.offset().top + 31 + "px", display: "block"});
                    lv2.html('<li><a href="#"><b><i>菜单二级菜单二级</i></b></a><ul class="lv3"><li class="up"></li><li><a href="#"><b><i>菜单三级</i></b></a></li><li class="cur"><a href="#"><b><i>菜单三级</i></b></a></li><li><a href="#"><b><i>菜单三级</i></b></a></li><li class="bottom"></li></ul></li><li><a href="#"><b><i>菜单二级</i></b></a></li><li class="bottom"></li>');
                    //lv2.css({width:"3000px"});
                    self.showHideMenu(obj, bool);
                }
            } else {
                obj.removeClass("move");
                // lv2.slideUp('fast');
                //lv2.css({left:"", top:"", display:""});
            }
        }
    };

    Plugin.prototype.allTowMenuHide = function () {
        this.$element.find(".menu_lv2_Obj .lv2").each(function () {
            //隐藏显示的二级菜单
            if ($(this).is(':visible')) {
                var n = lv1 = null, s = $(this).attr("id");
                if (s.indexOf("menu_lv2_") >= 0) {
                    n = s.replace("menu_lv2_", "");
                    lv1 = $("#menu_lv1_" + n);
                    lv1.removeClass("move");
                }
                //$(this).slideUp('fast');
                $(this).css({left: "", top: "", display: ""});
            }
        });
    };


    /**
     * 插件发布的方法
     * @type {string[] 数组元素=Plugin的方法名}
     */
    Plugin.publicMethods = [];


    /**
     * 定义jquery插件
     * @returns {$.fn}
     */
    $.fn.headMenu = function () {
        var userArgs = arguments;//用户调用$("selector").erTab()时传入的参数。此处保存下来，以便在下面的each中使用。
        var eachResult = [];//下面的each中，每次调用时返回的值
        this.each(function () {//循环处理每个jquery元素
            var $this = $(this);//注意，进入each方法后，需要$(this)包裹一下才是jquery对象

            //根据元素id从插件实例数组中筛选出已经创建的插件对象，如果元素未创建实例，则初始化一个，并增加到pluginArray。使用插件对象的目的是可以保持插件状态
            var plugin = $.grep(pluginArray, function (item, index) {
                return item['key'] === $this.attr("id");
            });
            if (plugin.length === 1) {
                plugin = plugin[0].value;
            } else {
                plugin = new Plugin($this);
                pluginArray.push({
                    key: $this.attr("id"),
                    value: plugin
                })
            }

            var args = $.merge([], userArgs);//复制一份userArgs。因为下面会改变这个数组
            var method = args[0];//需要执行的方法。如果用户需要执行插件中的某个方法，则方法名应该在第一个参数。如$("").erTab("addTab" , {});

            //解析应该调用的插件方法
            if ($.grep(Plugin.publicMethods, function (item) {//用户调用形式如$("").erTab("addTab")或$("").erTab("addTab" , {})时，将调用用户指定的插件方法
                    return item === method;
                }).length === 1) {
                method = plugin[method];//method设置为plugin中的方法
                args = Array.prototype.slice.call(args, 1);//方法参数。当前用户调用形式下，从第二个输入参数开始，都是方法的执行参数
            } else if (typeof(method) === 'object' || !method) {//用户调用形式如$("").erTab()或$("").erTab({})时，直接执行init方法，初始化插件
                args = userArgs;
                method = plugin._init;
            } else {//用户希望调用插件中的方法，但给出的方法名不正确，则抛出错误
                $.error('Method ' + method + ' does not exist on jQuery.headMenu');
            }

            //执行插件方法
            var methodResult = method.apply(plugin, args);

            //如果插件方法有返回值，则存储到eachResult
            if (methodResult !== undefined) {
                eachResult.push(methodResult);
            }
        });

        //如果eachResult有值，则返回eachResult，否则返回jquery元素本身（即this）
        return eachResult.length === 0 ? this : eachResult.length === 1 ? eachResult[0] : eachResult;
    }
})(jQuery, window, document);